package com.jx.demo.config;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.TimeUnit;

/**
 * 使用 @Configuration 注解的类，表示这是一个 Java 配置类（Configuration Class），用来替代传统的 applicationContext.xml 配置文件。
 * <p>
 * 在这个类中你可以通过 @Bean 注解来注册一个或多个 Bean。<bean id="myService" class="com.example.MyServiceImpl"/>
 * 常配合 @ComponentScan、@Import、@PropertySource 使用
 *
 * @ComponentScan("com.example") // 扫描包
 * @PropertySource("classpath:app.properties") // 引入外部配置
 * 类上加了 @Configuration 后，Spring 会使用 CGLIB 方式代理这个类，以保证 @Bean 方法不会被多次执行（也就是单例）。
 */
@Configuration
public class CacheConfig {
    @Bean
    public Cache<String, Object> caffeineCache() {
        Cache<String, Object> cache = Caffeine.newBuilder()
                // 初始容量
                .initialCapacity(100)
                // 最大缓存数量
                .maximumSize(500)
                // 缓存过期时间：写入缓存后，经过某个时间缓存失效
                .expireAfterWrite(3, TimeUnit.SECONDS)
                // 缓存失效监听器
                .removalListener((key, value, cause) -> System.out.println("key:" + key + " value:" + value + " cause:" + cause))
                // 开启统计功能
                .recordStats()
                .build();
        cache.put("name", "zzc");
        // 如果一个 key 不存在，那么会进入指定的函数生成 value
        cache.get("age", key -> "18");
        // 判断是否存在，如果不存在，则返回 null
        Object ageValue = cache.getIfPresent("age");
        // 移除一个key
        cache.invalidate("name");
        return cache;
    }
}
